﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ComicIsland.Common.Cache;

/**
 * 创建时间：2014/12/27 18:45:20
 * 作者：yong.blackcore
 * Email：itblackhole@outlook.com
 * QQ：50404503
 */
namespace ComicIsland.App.Controls
{
    public class CAsyncImageTask
    {
        private const int BUFFER_SIZE = 2048;

        private ICache cache;

        private string _sUrl;

        private WaitCallback callback;

        private HttpWebRequest request;

        private IAsyncResult iasyncresult;

        public ICache Cache
        {
            get
            {
                return this.cache;
            }
            set
            {
                this.cache = value;
            }
        }

        public IAsyncResult Iasyncresult
        {
            get
            {
                return this.iasyncresult;
            }
            set
            {
                this.iasyncresult = value;
            }
        }

        private string Url
        {
            get
            {
                return this._sUrl;
            }
            set
            {
                this._sUrl = value;
            }
        }

        public CAsyncImageTask(string sUrl)
        {
            this.Url = sUrl;
            this.callback = new WaitCallback(this.Load);
        }

        public void Dispose()
        {
            if (this.request == null)
            {
                return;
            }
            try
            {
                if (!this.iasyncresult.IsCompleted)
                {
                    this.request.EndGetResponse(this.iasyncresult);
                    this.request.Abort();
                }
            }
            catch
            {
            }
        }

        private void GetResponseCallback(IAsyncResult asynchronousResult)
        {
            byte[] array = null;
            int statusCode = 0;
            try
            {
                HttpWebResponse httpWebResponse = (HttpWebResponse)((HttpWebRequest)asynchronousResult.AsyncState).EndGetResponse(asynchronousResult);
                statusCode = (int)httpWebResponse.StatusCode;
                if (statusCode == 200)
                {
                    using (Stream responseStream = httpWebResponse.GetResponseStream())
                    {
                        try
                        {
                            BinaryReader binaryReader = new BinaryReader(responseStream);
                            MemoryStream memoryStream = new MemoryStream();
                            byte[] numArray = new byte[2048];
                            long contentLength = httpWebResponse.ContentLength;
                            int num = 0;
                            long num1 = (long)0;
                            while (true)
                            {
                                int num2 = binaryReader.Read(numArray, 0, 2048);
                                num = num2;
                                if (num2 == 0)
                                {
                                    break;
                                }
                                memoryStream.Write(numArray, 0, num);
                                num1 = num1 + (long)num;
                                if (this.LoadProcessEvent != null && contentLength > (long)0)
                                {
                                    this.LoadProcessEvent.Invoke(this, new LoadProcessEventArgs(num1, contentLength));
                                }
                            }
                            memoryStream.Flush();
                            array = memoryStream.ToArray();
                            memoryStream.Close();
                            binaryReader.Close();
                            if (this.cache != null)
                            {
                                this.cache.@add(this.Url, array);
                            }
                            if (this.LoadCompleteEvent != null)
                            {
                                this.LoadCompleteEvent.Invoke(this, new LoadCompleteEventArgs(array));
                            }
                        }
                        catch (Exception exception1)
                        {
                            Exception exception = exception1;
                            if (this.LoadErrorEvent != null)
                            {
                                this.LoadErrorEvent.Invoke(this, new LoadErrorEventArgs(statusCode, string.Concat("数据读写失败", exception.Message)));
                            }
                        }
                    }
                }
                else if (this.LoadErrorEvent != null)
                {
                    this.LoadErrorEvent.Invoke(this, new LoadErrorEventArgs(statusCode, string.Concat("HTTP请求错误 ", statusCode)));
                }
                httpWebResponse.Dispose();
            }
            catch (Exception exception3)
            {
                Exception exception2 = exception3;
                if (this.LoadErrorEvent != null)
                {
                    this.LoadErrorEvent.Invoke(this, new LoadErrorEventArgs(statusCode, string.Concat("网络请求错误", exception2.Message)));
                }
            }
        }

        private void Load(object o)
        {
            object obj = this.cache.@get(this.Url);
            if (obj == null)
            {
                this.LoadDataFromUrl(this.Url);
                return;
            }
            if (this.LoadCompleteEvent != null)
            {
                this.LoadCompleteEvent.Invoke(this, new LoadCompleteEventArgs(obj));
            }
        }

        private void LoadDataFromUrl(string url)
        {
            string str = url;
            try
            {
                this.request = WebRequest.CreateHttp(str);
                this.request.Headers["Accept-Language"] = "zh-cn,en-us;q=0.7,en;q=0.3";
                this.request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
                //this.request.UserAgent = Constants.UserAgent;
                this.iasyncresult = this.request.BeginGetResponse(new AsyncCallback(this.GetResponseCallback), this.request);
            }
            catch (Exception exception1)
            {
                Exception exception = exception1;
                if (this.LoadErrorEvent != null)
                {
                    this.LoadErrorEvent.Invoke(this, new LoadErrorEventArgs(0, string.Concat("网络请求错误,", exception.Message)));
                }
            }
        }

        public void Start()
        {
            ThreadPool.QueueUserWorkItem(this.callback);
        }

        public event Action<CAsyncImageTask, LoadCompleteEventArgs> LoadCompleteEvent;

        public event Action<CAsyncImageTask, LoadErrorEventArgs> LoadErrorEvent;

        public event Action<CAsyncImageTask, LoadProcessEventArgs> LoadProcessEvent;
    }


}
